from django.shortcuts  import render_to_response, get_object_or_404, redirect
from ventas_app.models import *
from django.db.models  import *
from django.template   import RequestContext
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
#from django.http import Http404
from ast         import literal_eval
from datetime    import datetime
from decimal     import Decimal
from django.utils.datastructures import MultiValueDictKeyError
from django.contrib.auth         import authenticate, login, logout

"""
    Renderiza el index del sistema de ventas que tiene un formulario para que el
    usuario se pueda loguear.
    El parametro mensaje puede tener los siguientes valores:
        0 : Muestra un mensaje de error al usuario de Clave o Id incorrectos.
        1 : Muestra un mensaje que indica que se ha deslogueado correctamente.
"""
def index(request, mensaje):
    if request.user.is_authenticated():
        return redirect(reverse('ventas_app.views.ver_vender'))
    else:
        diccionario = {'siguiente' : reverse('ventas_app.views.loguear')} #Direccion url de la pagina que loguea.
        if(mensaje == '0'):
            diccionario = dict(diccionario, **{'error':'Error: Clave o Usuario incorrectos.'})
        elif(mensaje == '1'):
            diccionario = dict(diccionario, **{'mensaje':'Se cerro sesion.'})
        
        return render_to_response( 'ventas_app/index.html',
                            diccionario,
                            context_instance=RequestContext(request),
                            )

""" Verifica e inicia la sesion del usuario enviado por POST: username = nick del usuario,
    password = contrasena.
"""
def loguear(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            return redirect(reverse('ventas_app.views.ver_vender'))
    
    
    return redirect(reverse('ventas_app.views.index', args = ['0']))

""" Cierra la sesion del usuario actual """
@login_required(login_url='/sistemacaja/_login')
def desloguear(request):
    logout(request)
    return redirect( reverse('ventas_app.views.index', args=['1']) )








"""
    Funcion Template para renderizar la vista de ventas
    El parametro "anadir_a_diccionario" recibe un diccionario que sera concatenado
    con el diccionario de contexto del template.
"""
def response_vender_productos(request, anadir_a_diccionario):
    lista_productos = Producto.objects.filter(cantidad__gt = 0).annotate(ventas = Count("ventaproducto")).order_by('-ventas')
    cinco_productos = lista_productos[:6]
    lista_clientes  = Usuario.objects.order_by('cedula');
    diccionario = {  'lista_productos' : lista_productos, #Lista de todos los productos
                     'cinco_productos' : cinco_productos, #Lista de los productos mas vendidos
                     'lista_clientes'  : lista_clientes,  #Lista de todos los clientes
                     'siguiente'       : reverse('ventas_app.views.comprar'),    #Direccion url de la pagina que recibe la orden de compra.
                     'salir'           : reverse('ventas_app.views.desloguear'), #Direccion url de la pagina para desloguear.
                     'usuario'         : request.user,                           #Usuario de la sesion.
                     }
    if(anadir_a_diccionario != None): diccionario = dict(diccionario, **anadir_a_diccionario)        
    return render_to_response(  'ventas_app/vista_ventas.html',
                                diccionario,
                                context_instance=RequestContext(request),
                                )


"""Vista para cuando hubo venta exitosa"""
@login_required(login_url='/sistemacaja/_login')
def compra_ok(request):
    return response_vender_productos(request, {'mensaje' : 'Venta realizada'})


"""Vista de ventas"""
@login_required(login_url='/sistemacaja/_login')
def ver_vender(request):
    return response_vender_productos(request, None)





""" Vista para guardar en la BD la compra, redirecciona de nuevo a la vista de ventas"""
@login_required(login_url='/sistemacaja/_login')
def comprar(request):
    productos = literal_eval(request.POST["productos"])
    pago      = literal_eval(request.POST["pago"])
    
    try:
        usr = get_object_or_404(Usuario, cedula = request.POST["cliente"])
    except MultiValueDictKeyError:
        n_c = literal_eval(request.POST["nuevo_cliente"])
        usr = Usuario(  nombre = n_c["nombre"],
                        cedula = n_c["cedula"],
                        carnet = n_c["carnet"],
                        saldo  = 0,
                        fecha  = datetime.now(),
                        tipo   = 'C')
    
    f = Factura( usuario = usr, fecha = datetime.now())
    f.save()
    
    for d in productos:
        prod = get_object_or_404(Producto, nombre = d["nombre"])
        
        pv = VentaProducto(producto = prod, factura = f, cantidad = d["cantidad"], precio = prod.precio_obj())
        pv.save()
        
        prod.cantidad -= pv.cantidad
        prod.save()
    
    if(pago['efectivo'] > 0):
        m = Movimiento(factura = f, tipo = 'E', cantidad = pago['efectivo'])
        m.save()
    if(pago['saldo'] > 0):
        m = Movimiento(factura = f, tipo = 'S', cantidad = pago['saldo'])
        m.save()
    if(pago['recarga'] > 0):
        m = Movimiento(factura = f, tipo = 'R', cantidad = pago['recarga'])
        m.save()
    
    usr.saldo += Decimal(pago['recarga']) - Decimal(pago['saldo']);
    usr.save();
    
    return redirect(reverse('ventas_app.views.compra_ok'))
